//
// TEST003.pde
//
// Read pressure sensor data from Arduino via serial interface and draw chart.
// In current sketch, Arduino sends data every 15 minutes.
// format of data as follows
// "xxxx.xx hpa yy.yy C"
//
// written by elekid.
//
// Processing site : http://processing.org
//

import processing.serial.*;

Serial port;
PFont myFont;

int cnt=0;

static int DATASIZE = 300;
float[] data = new float[DATASIZE];
String[] tag = new String[DATASIZE];

static int chartX = 50;
static int chartY = 10;
static int chartWidth = 600;
static int chartHeight = 400;

static int chartBackground = 240;
static int chartBackgroundNight = 215;

color dataColor = color(24, 24,128 );
color msgColor = color(255,0,0);
color lineColor = color(128);

float maxdata;
float mindata;
int intMaxdata;
int intMindata;


// for future use
static int defaultMaxBaro=1010;
static int defaultMinBaro=999;

static String DATAFILE = "timedata.txt";


/**
 * setup()
 */
void setup(){
  myFont = createFont("SansSerif", 18);
  println(Serial.list());
  size (660,480);

  // Assuming that 3rd serial port is connected to Arduino
  port = new Serial(this, Serial.list()[2], 9600);

  // Data will be available when NL(LF) receive.
  // LF文字受信でシリアルイベントが通知される
  port.bufferUntil(10);

  // draw() will be called every x seconds.
  // フレームレートを毎秒1フレームにする
  // CPU使用率を下げるため
  frameRate(0.5);


  // DEBUG
  /*
*/
  /*
  addData("21:30", 1003.07);
  addData("21:45", 1003.08);
  */
  // [2010/6/14 21:45:19] 1003.08 hPa 27.50 C
  final String dummy = "POST 1003.08 1003.07 1003.27 1003.27 1003.22 1002.94 1002.86 1002.66 1002.77 1002.9 1002.98 1003.02 1002.97 1002.96 1002.97 1003.02 1003 1003.22 1003.47 1003.32 1002.88 1002.92 1003.62 1004.27 1004.37 1004.52 1004.81 1004.78 1005.14 1005.47 1005.35 1005.59 1005.84 1005.88 1005.88 1006.18 1006.27 1006.53 1006.64 1006.95 1006.91 1007.15 1007.32 1007.48 1007.44 1007.66 1007.94 1007.89 1008.13 1008.16 1008.15 1008.27 1008.23 1008.25 1008.46 1008.33 1008.29 1008.33 1008.23 1008.08 1008.03 1007.39 1008.04 1008 1007.8 1007.69 1007.71 1007.61 1007.65 1007.66 1007.77 1007.63 1007.52 1007.39 1007.13 1007.09 1006.97 1007.12 1007.06 1006.97 1006.99 1007.03 1006.96 1007.21 1007.4 1007.38 1007.54 1007.51 1007.88 1007.69 1007.91 1008.08 1008.09 1008.19 1008.34 1008.12 1008.09 1008.15 1008.1 1007.73 1007.86 1007.79 1007.85 1007.78 1007.67 1007.55 1007.59 1006.64 1006.93 1007.71 1007.79 1007.78 1007.64 1007.79 1007.53 1007.4 1007.2 1007 1006.83 1006.73 1006.73 1006.85 1006.97 1007 1007.59 1007.82 1007.91 1008.01 1008.02 1008.36 1008.4 1008.19 1008.25 1008.41 1008.34 1008.33 1008.37 1008.46 1008.37 1008.15 1008.24 1008 1007.91 1007.89 1007.67 1007.65 1007.73 1007.55 1007.4 1007.41 1007.2 1007.26 1007.13 1006.83 1006.72 1006.36 1006.3 1006.14 1005.99 1005.8 1005.95 1005.85 1005.89 1005.76 1005.72 1005.69 1005.75 1005.81 1005.82 1005.77 1005.59 1005.55 1005.44 1005.54 1005.54 1005.51 1005.48 1005.51 1005.34 1005.44 1005.4 1005.35 1005.35 1005.41 1005.51 1005.63 1005.26 1005.14 1004.94 1004.96 1004.89 1004.75 1004.35 1003.94 1003.94 1003.93 1003.94 1004.01 1004.16 1004.16 1004.32 1004.05 1004.15 1004.01 1003.97 1003.95 1004.13 1004.05 1004.03 1004.17 1003.74 1003.71 1003.81 1003.87 1004.03 1004.16 1004.36 1004.3 1004.38 1004.43 1004.28 1004.5 1004.71 1004.92 1004.91 1005.24 1005.51 1005.66 1005.71 1005.97 1006.05 1006.16 1006.37 1006.54 1006.45 1006.58 1006.75 1006.75 1006.7 1006.59 1006.59 1006.66 1006.83 1006.65 1006.53 1006.38 1006.47 1006.36 1006.45 1006.47 1006.26 1006.26 1006.21 1006.06 1005.92 1005.85 1005.85 1005.64 1005.73 1005.77 1005.69 1005.85 1005.79 1005.79 1005.85 1005.79 1006.11 1006.04 1006.41 1006.91 1006.95 1006.88 1007.17 1007.11 1007.35 1007.41 1007.69 1007.53 1007.44 1007.51 1007.31 1007.24 1007 1006.87 1006.65 1006.66 1005.91 1005.83 1005.69 1006.39 1006.41 1006.25 1006.22 1006.31 1006.34 1006.35 1006.48 1006.49 1006.43 1006.66 1006.57 1006.76 1006.5 1006.56 1006.31 1006.34 1006.63 1006.65 1006.78 1006.65 1006.64 1006.92 1006.82 1007.03 1007.18 1007.17 1007.17 1007.37 1007.57 1007.83 1007.69 1007.77 1007.82 1008.19 1008.24 1008.19 1008.35 1008.2 1008.22 1008.35 1008.29 1008.36 1008.48 1008.39 1008.09 1007.93 1007.83 1007.16 1007.61 1007.6 1007.48 1007.38 1007.26 1007.07 1007.1 1006.8 1006.97 1006.74 1006.78 1006.64 1006.82 1006.77 1006.7 1006.61 1006.65 1006.43 1006.58 1006.55 1006.6 1006.65 1006.65 1006.57 1006.74 1007.03 1006.78 1006.75 1006.75 1006.62 1006.71 1006.56 1006.52 1006.35 1006.14 1005.64 1005.82 1005.67 1004.76 1005.1 1004.98 1004.84 1004.74 1004.22 1003.8 1003.71 1003.11 1003.37 1003.29 1003.45 1003.28 1003.26 1003.13 1003.08 1003.08 1003.09 1002.99 1003.14 1003.17 1003.33 1003.47 1003.6 1003.89 1003.97 1004.03 1004.37 1004.52 1004.53 1004.72 1005.05 1005.23 1005.37 1005.56 1005.71 1005.78 1006.09 1006.12 1006.22 1006.08 1006.16 1006.31 1006.18 1006.34 1006.58 1006.43 1006.19 1006.23 1006.19 1005.58 1006.09 1006.1 1006.07 1005.84 1005.69 1005.66 1005.55 1005.53 1005.53 1005.22 1005.34 1005.39 1005.32 1005.23 1005.14 1005.2 1005.45 1005.39 1005.61 1005.58 1005.59 1005.67 1005.67 1005.86 1006.07 1005.73 1005.73 1005.78 1005.98 1006.16 1006.02 1006.14 1006.07 1006.05 1006.12 1006.03 1006.11 1006.05 1006.04 1005.94 1005.69 1005.7 1005.8 1005.55 1005.47 1005.31 1005.34 1005.08 1004.5 1004.94 1004.85 1004.92 1004.78 1004.78 1004.73 1004.9 1005.02 1004.6 1004.8 1005.11 1005.26 1005.44 1005.53 1005.91 1005.81 1005.99 1005.94 1006.16 1006.14 1006.17 1006.4 1006.44 1006.02 1007 1006.96 1007.02 1006.96 1007.35 1007.61 1007.78 1007.91 1007.89 1008.11 1007.98 1007.91 1007.59 1007.51 1007.39 1007.68 1007.64 1007.91 1007.92 1007.68 1007.46 1007.34 1007.17 1007.04 1006.8 1006.61 1006.48 1006.34 1006.36 1006.22 1006.12 1006.17 1006.32 1006.41 1006.48 1006.35 1006.49 1006.47 1006.6 1006.56 1006.54 1006.73 1006.73 1006.78 1006.71 1006.74 1006.78 1007.09 1007.03 1007.05 1007.08 1006.54 1007.27 1007.39 1007.47 1007.42 1007.56 1007.57 1007.74 1007.81 1007.59 1007.6 1007.45 1007.52 1007.52 1007.54 1007.43 1007.4 1007.38 1007.42 1006.53 1006.6 1006.28 1006.94 1006.84 1006.78 1006.76 1006.88 1007 1006.69 1006.9 1007.15 1007.03 1007.53 1007.65 1007.37 1007.38 1007.52 1007.82 1007.6 1007.66 1007.73 1007.86 1008.01 1008.18 1008.51 1008.59 1008.56 1008.97 1009.04 1009.04 1009.2 1009.19 1008.97 1008.6 1009.41 1009.53 1009.62 1009.62 1009.62 1009.6 1009.61 1009.94 1010 1009.92 1009.99 1009.94 1010.09 1009.82 1009.78 1009.61 1009.57 1009.2 1009.18 1008.9 1008.92 1008.85 1008.73 1008.75 1008.66 1008.75 1008.53 1008.71 1008.61 1008.62 1008.52 1008.55 1008.51 1008.79 1008.75 1008.87 1008.79 1008.92 1008.91 1009.47 1009.5 1009.4 1009.31 1009.16 1009.16 1009.22 1009.16 1009.26 1009.37 1009.13 1008.91 1008.79 1008.73 1008.79 1008.67 1008.48 1008.41 1008.32 1008.29 1007.62 1008.04 1007.85 1007.9 1007.7 1007.76 1007.76 1007.51 1007.71 1007.36 1007.38 1007.39 1007.27 1007.4 1007.33 1007.29 1007.39 1007.56 1007.59 1007.72 1007.61 1007.66 1007.8 1007.91 1008.02 1008.02 1008.08 1008.2 1008.51 1008.55 1008.74 1008.72 1008.68 1008.67 1008.87 1008.95 1008.93 1008.93 1008.91 1009.01 1009.32 1009.1 1009.42 1009.74 1009.8 1009.81 1009.73 1009.34 1009.49 1008.62 1009.2 1009.18 1009.23 1009.35 1009.12 1008.92 1008.69 1008.41 1008.44 1008.23 1008.09 1008 1008.36 1008.08 1008.22 1008.04 1008.03 1007.82 1008.04 1008.06 1008.06 1007.71 1007.59 1007.51 1007.61 1007.46 1007.64 1007.58 1007.82 1007.81 1007.59 1007.53 1007.51 1007.59 1007.51 1007.63 1007.55 1007.3 1007.37 1007.53 1007.2 1007.02 1006.9 1006.63 1006.59 1006.75 1006.54 1006.44 1006.07 1005.92 1005.89 1005.65 1005.53 1005.48 1005.63 1005.5 1005.31 1005.16 1005.09 1005.1 1005.22 1004.95 1005.05 1005.25 1005.18 1005.22 1005.04 1005.35 1005.24 1005.26 1005.43 1005.71 1005.87 1006.07 1006.27 1006.32 1006.44 1006.45 1006.64 1006.75 1006.8 1006.83 1006.99 1006.93 1006.92 1007.04 1006.96 1006.73 1006.97 1006.92 1006.95 1006.87 1007.08 1007.07 1006.95 1006.97 1006.9 1006.7 1006.44 1006.5 1006.33 1006.43 1006.06 1005.84 1005.75 1005.57 1005.39 1005.21 1005.2 1005.09 1004.95 1004.92 1004.84 1004.78 1004.68 1004.67 1004.78 1004.79 1004.73 1004.73 1004.93 1004.78 1004.82 1004.73 1005.01 1005.17 1005.19 1005.16 1005.02 1005.31 1005.44 1005.52 1005.32 1005.47 1005.38 1005.14 1004.89 1004.81 1004.64 1004.23 1004.07 1003.72 1003.63 1003.53 1003.39 1002.85 1003.02 1002.77 1002.59 1002.41 1002 1002.16 1002.11 1001.79 1001.88 1001.87 1001.68 1001.84 1001.79 1001.83 1002.03 1001.75 1001.88 1001.85 1001.94 1002.16 1002.42 1002.5 1002.38 1002.98 1003.01 1003.19 1003.42 1003.71 1003.87 1004.14 1004.53 1004.68 1004.78 1004.89 1005.04 1004.98 1005.02 1004.82 1004.72 1005.11 1004.88 1004.8 1004.7 1004.82 1004.54 1004.33 1004.08 1003.68 1004.19 1004.22 1004.18 1004.12 1004.05 1004.14 1004.1 1004.05 1004.16 1003.86 1003.83 1003.47 1003.47 1003.28 1003.17 1003.32 1003.63 1003.79 1003.82 1003.93 1004.1 1004.4 1004.58 1004.89 1004.93 1005.07 1005.37 1005.02 1004.9 1005.29 1005.34 1005.28 1005.24 1005.22 1005.17 1005.04 1005.17 1005.06 1004.87 1004.83 1004.72 1004.6 1004.26 1004.11 1004 1004.05 1003.26 1003.16 1002.82 1003.42 1003.57 1003.67 1003.47 1003.38 1003.15 1003.37 1003.52 1003.38 1003.16 1003.61 1003.78 1003.75 1003.93 1004.04 1004.15 1004.64 1004.69 1004.8 1005.31 1005.12 1005.23 1005.25 1005.47 1005.72 1005.83 1006.09 1006.34 1006.61 1006.7 1006.86 1006.92 1007.32 1007.5 1007.68 1007.63 1008 1008.05 1008.05 1007.9 1008.13 1008.25 1008.34 1008.43 1008.46 1008.36 1008.46 1008.4 1008.28 1008.09 1008.24 1008.21 1008.25 1008.34 1008.31 1008.03 1007.95 1008.03 1007.76 1007.73 1007.72 1007.7 1007.72 1007.83 1007.92 1007.86 1008.01 1008.03 1007.91 1008.15 1008.34 1008.09 1008.34 1008.6 1008.58 1008.34 1008.73 1008.57 1008.76 1009.07 1009.26 1009.42 1009.1 1009.28 1009.38 1009.53 1009.49 1009.5 1009.44 1009.33 1009.2 1009.05 1009.14 1009.04 1009.02 1009.09 1008.43 1008.29 1008.97 1008.99 1008.95 1009.03 1009.14 1009.29 1008.54 1008.34 1008.32 1008.19 1008.53 1008.34 1008.17 1008.16 1008.15 1008.27 1008.18 1008.22 1008.3 1008.47 1008.61 1008.91 1009.06 1009.16 1009.39 1009.59 1009.79 1009.99 1010.26 1010.38 1010.68 1010.72 1011 1011.16 1011.33 1011.39 1011.52 1011.59 1011.67 1011.72 1011.85 1011.83 1011.87 1012.01 1011.93 1011.97 1011.25 1011.93 1011.9 1011.84 1011.84 1011.73 1011.69 1011.58 1011.47 1011.3 1011.2 1011.28 1011.21 1011.28 1011.14 1011.2 1011.15 1011.17 1011.27 1011.31 1011.36 1011.26 1011.27 1011.26 1011.36 1011.31 1011.4 1011.27 1011.45 1011.43 1011.49 1011.67 1011.87 1011.75 1011.87 1011.73 1011.88 1011.92 1011.77 1011.78 1011.8 1011.58 1011.42 1011.08 1010.85 1010.56 1010.47 1010.19 1009.27 1009.76 1009.69 1009.68 1009.39 1009.22 1009.17 1008.99 1008.97 1008.91 1008.86 1008.7 1008.65 1008.63 1008.66 1008.71 1008.84 1008.94 1009.06 1008.94 1009.15 1009.12 1009.27 1009.21 1009.39 ";
   
  // addAllData(dummy);
  
  readDataFile();

  // DEBUG END
}

/**
 * draw()
 */
void draw(){
  background(210);
  smooth();

  // draw graph area
  noStroke();
  fill(chartBackground);
  rect( chartX, chartY, chartWidth, chartHeight);

  // colorize graph area
  colorArea();

  // draw graph
  plotDataLabel();
  drawChart();

  // display current value
  textFont(myFont, 18);
  fill(msgColor);
  text ("now : ", 170 , chartY + 20 );
  textFont(myFont, 24);
  int hpa_disp=int((float)(data[0]*2)/2);
  text(hpa_disp, 215, chartY + 20);
  textFont(myFont, 18);
  text ("hPa", 275 , chartY + 20 );

}

/**
 * serialEvent()
 *
 * automatically called when Serial data is available.
 * シリアルからのデータ受信時に自動的に呼び出される。
 */
void serialEvent(Serial p) {

  String inString = (port.readString());
  saveLogFile(inString);
  String[] s=split(inString, " ");

  if (s[0].equals("POST")) {
    if ( cnt > 0 ) {
      println("POST ignored.");
    } else {
      addAllData(inString);
    }
    return;
  } else if ( s[0].equals("DEBUG")) {
    println("DEBUG ignored.");
    return;
  }

  String hhmm = String.format("%02d", hour()) + ":" 
  + String.format("%02d", minute());
  println(s[0] + " / " + hhmm);

  addData(hhmm, float(s[0]));
  addDataFile(hhmm, s[0]);

}

/**
 * addData()
 *
 * store sensor data into array
 * シリアルで受信したセンサーのデータを配列にセットする
 * 配列の要素数は有限なので、古いものから上書きされて行く
 * 最新は要素0に保管
 */
void addData(String msg, float hpa) {

  cnt++;
  if ( cnt > DATASIZE) {
    cnt = DATASIZE;
  }

  // store latest data into data[0],
  for ( int i=cnt-1 ; i > 0 ; i--){
    data[i]=data[i-1];
    tag[i] = tag[i-1];
  }
  data[0] =hpa;
  tag[0] = msg;

  maxdata = data[0] ;
  mindata = data[0] ;

  for ( int i = 1 ; i < cnt ; i++) {
    if ( data[i] > maxdata ){
      maxdata = data[i];
    }
    if (data[i] < mindata ){
      mindata = data[i];
    }
  }
  if ( int(mindata) < defaultMinBaro ) {
    intMindata = int(mindata);
  } 
  else {
    intMindata = defaultMinBaro;
  }
  if ( int(maxdata) > defaultMaxBaro ) {
    intMaxdata = int (maxdata)+1;
  } 
  else {
    intMaxdata = defaultMaxBaro;
  }
}

/**
 * drawChart()
 *
 * draw line chart
 * vertex()により折れ線グラフを描画する
 */
void drawChart(){
  stroke(dataColor);
  noFill();
  strokeWeight(2);

  beginShape();
  for (int i = 0 ; i <cnt ; i++){
    float x = getX(i);
    float y = getY(data[i]);
    vertex( x ,y );
    if ( i-1 == cnt || i == 0) {
      vertex( x ,y );
    }
  }
  endShape();

}

/**
 * plotDataLabel()
 *
 * plot x/y axis labels
 * x軸及びy軸の描画、データラベルも
 */
void plotDataLabel(){
  textFont(myFont,10);
  for ( int v = intMindata ; v <= intMaxdata ; v++) {
    noFill();
    strokeWeight(1);
    stroke(lineColor);
    line ( chartX , getY(v), chartX+chartWidth, getY(v));
    fill(dataColor);
    text(v,chartX-30,getY(v)+5);

  }

  for ( int v = 0 ; v < DATASIZE ; v += 4) {
    noFill();
    strokeWeight(1);
    stroke(lineColor);
    line ( getX(v) , getY(intMaxdata), getX(v), getY(intMindata));
  }

  for ( int v = 0 ; v < DATASIZE ; v+=8) {
    if ( v >= cnt ) break;
    pushMatrix();
    translate(getX(v),getY(intMindata)+30);
    rotate(PI*3/2);
    fill(dataColor);
    text(tag[v],0,0);
    popMatrix();

  }
}

/*
* getX()
 *
 * calc x value
 * 描画の際の基準となるx値を計算する
 */
float getX (int cnt){
  float x = chartX + chartWidth - (cnt * chartWidth / DATASIZE);
  return x;
}

/*
* getY()
 *
 * calc y value
 * 描画の際の基準となるy値を計算する。
 */
float getY(float val){
  float y = chartY + (1 + intMaxdata - val) * chartHeight / (intMaxdata -
    intMindata+2);
  return y;
}

/*
* saveLogFile()
 *
 * save sensor data into log file
 * シリアルで受信したデータにタイムスタンプを付与してログファイルに保存する
 * ファイルはスケッチの保存ディレクトリに作成される
 */
void saveLogFile(String outString) {
  String buffer = "[";
  buffer += String.valueOf(year());
  buffer += "/";
  buffer += String.valueOf(month());
  buffer += "/";
  buffer += String.valueOf(day());
  buffer += " ";
  buffer += String.format("%02d", hour());
  buffer += ":";
  buffer += String.format("%02d", minute());
  buffer += ":";
  buffer += String.format("%02d", second());
  buffer += "] ";
  buffer += outString;

  // open existing file
  // 初回実行時にはゼロバイトでファイルを作成しておく必要がある
  String[] lines = loadStrings("sensor_data.log");
  String[] newlines= append( lines, buffer);

  // add one line and save
  saveStrings("sensor_data.log", newlines);
  print(buffer);
}

/*
 * colorArea()
 *
 * 日付の変わり目の視認性を向上させるため
 * グラフの中で深夜 0:00 前後のエリアの背景色を暗くする
 */
void colorArea(){
  int [] MidNight = {
    0   };
  int pos=0;
  boolean foundFlg = false ;
  boolean foundFlgPrev = false ;

  for ( int i = 0 ; i < cnt ; i++){
    String[] s=split(tag[i], ":");
    // 0:xx found
    if (int(s[0]) == 0 ) {
      foundFlg=true;
      if ( MidNight.length < pos + 1) {
        MidNight = append(MidNight, 0);
      }
      // println("pos=" + pos);
      // println(" i=" + i);
      MidNight[pos] = i ;
    }
    else {
      foundFlg=false;
    }
    if ( (foundFlg == false) && (foundFlgPrev == true) ) {
      pos++;
    }
    foundFlgPrev=foundFlg;
  }

  for ( int i = 0 ; i < MidNight.length ; i++ ){
    // datasize = 200
    // width= 400
    // --> 15 min = 2pixcel
    // --> 6 hour = 6 * 4 * 2= 48 pixcel
    // -->
    float mx = getX(MidNight[i]);
    if ( (mx -48 ) >= chartX && ( mx + 48 <= chartX + chartWidth )) {
      for (int j = 0 ; j < 96 ; j++ ){
        if ( j < 10 ) {
          stroke(chartBackground - j* 2 );
        }
        else if (j > 86 ) {
          stroke(chartBackground - (96-j)* 2 );
        }
        else {
          stroke (chartBackgroundNight);
        }
        // line( x, y, x, y2 );
        line (mx - 48 + j, getY(intMaxdata), mx - 48 + j ,
        getY(intMindata));
      }
    }
    else if ( (mx -48 ) >= chartX && ( mx <= chartX + chartWidth )) {
      //println ("mx = " + mx);
      //println ("chartX + chartWidth - mx=" + (chartX + chartWidth - mx));
      for (int j = 0 ; j <= (48+(chartX + chartWidth - mx)) ; j++ ){
        if ( j < 10 ) {
          stroke(chartBackground - j* 2 );
        }
        else {
          stroke (chartBackgroundNight);
        }
        // line( x, y, x, y2 );
        line (mx - 48 + j, getY(intMaxdata), mx - 48 + j , getY(intMindata));
      }
    }
    else if ( ( mx + 48 <= chartX + chartWidth ) && mx >= chartX) {
      // TODO
      for (int j=0 ; j <= (mx - chartX + 48) ; j++){
        float c = (mx - chartX + 48) - j;
        if ( c <= 10 ){
          stroke(chartBackground - c * 2 );
        }
        else {
          stroke (chartBackgroundNight);
        }
        line (chartX + j, getY(intMaxdata), chartX + j , getY(intMindata));
      }

    }

  }
}

/*
 * addAllData()
 *
 * recieve bunch of data from Arduino and store them (experimental)
 * Arduinoからのデータ一括送信(POST)を取り込む (実験的)
 */

void addAllData (String data) {
  // assuming that s1 contains "POST xxxx.xx xxxx.xx ....LF"
  String[] s1 = split(data, " ");
  // println("step.1  s1 len :" + s1.length);

  // eliminate null string or LF
  for ( int i = s1.length-1 ; i >= 0 ; i-- ) {
    if (s1[i].length() <= 1 ) {
      // println("shorten");
      s1=shorten(s1);
    } else {
      // println("break");
      break;
    }
  }
  // println("step.2  s1 len :" + s1.length);
  // delete POST message from array
  s1 = subset(s1,1);

  // println("step.3  s1 len :" + s1.length);

  String[] h1= new String[s1.length];
  int hhmm = hour()*60 + minute();
  
  // assuming that last measuring time is 15 min before current time
  // sampling rate is also 15min
  for ( int i=0 ; i < h1.length ; i++) {
    hhmm = hhmm - 15;
    if (hhmm < 0 ) {
      hhmm = hhmm + 24*60;
    }
    h1[i] = mms2hhmm(hhmm);
  }
  // println("h1 len :" + h1.length);

  
  // now we have all data and approximate time in line.
  // in order to use addData() method to these data,
  // we have to create reverse data 
  
  s1 = reverse(s1);
  h1 = reverse(h1);

  // println("s2 len :" + s1.length);
  println("POST data count:" + h1.length);
  
  for ( int i=0 ; i < h1.length ; i++) {
    addData( h1[i], Float.parseFloat(s1[i]) );
  }

}


/*
 * mms2hhmm()
 * convert minutes (>60) to "hh:mm" (string)
 */
String mms2hhmm(int hhmm){
   int hh = hhmm / 60 ;
   int mm = hhmm - hh*60;
   return ( String.format("%02d", hh) + ":" + String.format("%02d",mm) );
}

/*
 * addDataFile()
 * Store sensor data into data file
 * センサーのデータをデータファイルに保存する
 */
void addDataFile(String hhmm, String hpa){
  String[] s ;
  String[] lines = loadStrings(DATAFILE);
  int start=0;
  int i,j;

  String[] newlines = new String[DATASIZE];

  // if max reached or exceeded
  if ( lines.length >= DATASIZE ) {
    start = lines.length - DATASIZE + 1;
  }
  for (i = start,j=0 ; i < lines.length ; i++,j++ ) {
    s =split(lines[i], ",");
    newlines[j]=s[0]+","+s[1];
  }
  newlines[j]=hhmm+"," + hpa;
  saveStrings(DATAFILE, newlines);
}


/*
 * readDataFile()
 *
 * read sensor data from data file, called on startup
 * prevent data lost on restarting
 * データファイルから過去データを読み出す
 * 起動時に呼び出される
 * 再起動時にデータが初期化されてしまうのを予防する
 */
void readDataFile(){
  String[] s ;
  String[] lines = loadStrings(DATAFILE);
  for (int i = 0 ; i < lines.length ; i++ ) {
    s =split(lines[i], ",");
    /*
    if (s[0].startWith("#") == false ){
      println(s[0] + " : " + s[1]");
    }
    */
    addData( s[0], Float.parseFloat(s[1]) );
    
  }
}
  
